import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:whitesdk/room.dart';

export 'package:whitesdk/room.dart';

class WhiteBoardSdkConfiguration {
  final String appIdentifier;
  final bool log;
  final int viewId;

  WhiteBoardSdkConfiguration(this.viewId, this.appIdentifier, this.log);
}

abstract class AbstractCommonCallbacks {
  void urlInterrupter(String sourceUrl);
  void sdkSetupFail(String error);
  void throwError(String args);
  void onPPTMediaPlay();
  void onPPTMediaPause();
}

class WhiteBoardSdk {
  final WhiteBoardSdkConfiguration configuration;
  final AbstractCommonCallbacks abstractCommonCallbacks;
  final MethodChannel methodChannel;
  WhiteBoardSdk(this.configuration, [this.abstractCommonCallbacks]) :
    methodChannel = MethodChannel("plugins.netless.link/whiteboard_"+ configuration.viewId.toString()) {
      methodChannel.setMethodCallHandler((call) async {
        switch (call.method) {
          case 'urlInterrupter':
            abstractCommonCallbacks?.urlInterrupter(call.arguments["sourceUrl"]);
            break;
          case 'sdkSetupFail':
            abstractCommonCallbacks?.sdkSetupFail(call.arguments["error"]);
            break;
          case 'throwError':
            abstractCommonCallbacks.throwError(call.arguments["args"]);
            break;
          case 'onPPTMediaPlay':
            abstractCommonCallbacks?.onPPTMediaPlay();
            break;
          case 'onPPTMediaPause':
            abstractCommonCallbacks?.onPPTMediaPause();
            break;
          case 'onPhaseChanged':
            abstractRoomCallbacks?.onPhaseChanged(call.arguments["phase"]);
            break;
          case 'onRoomStateChanged':
            abstractRoomCallbacks?.onRoomStateChanged(call.arguments["modifyState"]);
            break;
          default:
            break;
        }
      });

      methodChannel.invokeMethod("createSdk", <String, dynamic>{
        "appId": configuration.appIdentifier,
        "log": configuration.log
      });
    }

  AbstractRoomCallbacks abstractRoomCallbacks;

  Future<WhiteBoardSdkRoom> joinRoom(RoomParams params, [AbstractRoomCallbacks callbacks]) async {
    this.abstractRoomCallbacks = callbacks;
    int memberId = await methodChannel.invokeMethod("joinRoom", params.toJson());
    return WhiteBoardSdkRoom(
      methodChannel,
      memberId
    );
  }
}

typedef void OnWhiteBoardSdkPlatformViewCreated(int viewId);

class WhiteBoardSdkPlatformView extends StatelessWidget {

  final OnWhiteBoardSdkPlatformViewCreated onWhiteBoardSdkPlatformViewCreated;

  const WhiteBoardSdkPlatformView({Key key, this.onWhiteBoardSdkPlatformViewCreated}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return PlatformViewLink(
      viewType: 'plugins.netless.link/whiteboard',
      onCreatePlatformView: (PlatformViewCreationParams params) {
        return PlatformViewsService.initSurfaceAndroidView(
          id: params.id,
          viewType: 'plugins.netless.link/whiteboard',
          layoutDirection: TextDirection.rtl,
          creationParams: {},
          creationParamsCodec: const StandardMessageCodec(),
        )
          ..addOnPlatformViewCreatedListener(params.onPlatformViewCreated)
          ..addOnPlatformViewCreatedListener((int id) {
            if (onWhiteBoardSdkPlatformViewCreated == null) {
              return;
            }
            onWhiteBoardSdkPlatformViewCreated(id);
          })
          ..create();
      },
      surfaceFactory: (BuildContext context, PlatformViewController controller) {
       return PlatformViewSurface(
           gestureRecognizers: const <Factory<OneSequenceGestureRecognizer>>{},
           controller: controller,
           hitTestBehavior: PlatformViewHitTestBehavior.opaque,
       );
      },
   );
  }
}